/*********************************************************************
* File: CombatAndFinancesSampleAgent.cpp
*
* Implements the combat and finances API sample. 
*
* \author Instituto Superior Tecnico de Lisboa, Portugal
* \author Technical University of Lisbon, Portugal
* 
* \author Agentes Autonomos e Sistemas Multiagente
* \author Autonomous Agents and Multiagent Systems
* 
* \version	1.0
* \date		2006/2007
*********************************************************************/
#include "CombatAndFinancesSampleAgent.h"
using namespace agents::samples;

#define TIMEOUT_NOT_DEFINED -1

#include "../../util/debug.h"
#include "../../util/util.h"
using namespace util;

CombatAndFinancesSampleAgent::CombatAndFinancesSampleAgent(edict_t *enity, int team, int model)
:Agent(enity, team, model)
{
	for(int i=0; i<Operations::max; i++)
	{
		records[i].timeout = TIMEOUT_NOT_DEFINED;
		records[i].enabled = false;
	}
	stop();
}

CombatAndFinancesSampleAgent::~CombatAndFinancesSampleAgent(){}

void CombatAndFinancesSampleAgent::stop()
{
	_isAiming = false;
	for(int i=0; i<Operations::max; i++)
		records[i].enabled = false;
}

void CombatAndFinancesSampleAgent::think()
{
	if(_isAiming)
		if(getCombat().isAimingAt(_aimTarget))
			_isAiming = false;
		else
			getCombat().aimAt(_aimTarget);

	for(int i=0; i<Operations::max; i++)
	{
		if(records[i].timeout != TIMEOUT_NOT_DEFINED)
			if(records[i].timeout <= getWorld().getTime())
			{
				records[i].timeout = TIMEOUT_NOT_DEFINED;
				records[i].enabled = false;
			}
	}

	if(records[Operations::aimLeft].enabled)
		getCombat().aimLeft();
	if(records[Operations::aimRight].enabled)
		getCombat().aimRight();
	if(records[Operations::aimUp].enabled)
		getCombat().aimUp();
	if(records[Operations::aimDown].enabled)
		getCombat().aimDown();

	ICommunication::MessageRecord record;
	if(getCommunication().receiveMsg(ICommunication::SayMessages::sayMsg, &record))
		handleMessage(record);
	else if(getCommunication().receiveMsg(ICommunication::SayMessages::sayTeamMsg, &record))
		handleMessage(record);
	else if(getCommunication().receiveMsg(ICommunication::SayMessages::sayDeadMsg, &record))
		handleMessage(record);
}
void CombatAndFinancesSampleAgent::handleMessage(ICommunication::MessageRecord &record)
{
	char msgBuffer[256];
	char command[32];
	char arg1[32];
	char arg2[32];

	strcpy(arg1, "");
	strcpy(arg2, "");
	sscanf(record.msg, "%s %s %s", command, arg1, arg2);

	if((strcmp(command,"fireP")==0) || (strcmp(command,"fP")==0))
	{   
		getCombat().primaryAttack();
		sprintf(msgBuffer, "Primary attack.\n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"fireS")==0) || (strcmp(command,"fS")==0))  
	{
		getCombat().secondaryAttack();
		sprintf(msgBuffer, "Secondary attack.\n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"reload")==0) || (strcmp(command,"r")==0)) 
	{
		getCombat().reloadWeapon();
		sprintf(msgBuffer, "Reloading.\n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"selectP")==0) || (strcmp(command,"sP")==0))
	{
		getCombat().selectPrimaryWeapon();
		sprintf(msgBuffer, "Selecting primary weapon.\n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"selectS")==0) || (strcmp(command,"sS")==0))
	{
		getCombat().selectSecondaryWeapon();
		sprintf(msgBuffer, "Selecting secondary weapon.\n");
		getCommunication().sayText(msgBuffer);
	}
	else if(strcmp(command,"select")==0)
	{
		getCombat().selectWeapon(arg1);
		sprintf(msgBuffer, "Selecting weapon '%s'.\n", arg1);
		getCommunication().sayText(msgBuffer);
	}
	else if(strcmp(command,"has")==0)
	{
		if(getCombat().hasWeapon(arg1))
			sprintf(msgBuffer, "I have '%s'.\n", arg1);
		else
			sprintf(msgBuffer, "I don't have '%s'.\n", arg1);
		getCommunication().sayText(msgBuffer);
	}
	else if(strcmp(command,"drop")==0)
	{
		getCombat().drop();
		sprintf(msgBuffer, "Dropped weapon.\n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"buy")==0) || (strcmp(command,"b")==0))
	{
		getFinances().buy(arg1);
		sprintf(msgBuffer, "Buying weapon '%s'.\n", arg1);
		getCommunication().sayText(msgBuffer);
	}
	else if(strcmp(command,"money")==0)
	{
		sprintf(msgBuffer, "Money: %d \n", getFinances().money());
		getCommunication().sayText(msgBuffer);
	}
	else if(strcmp(command,"ammo")==0)
	{
		sprintf(msgBuffer, "Ammo: %d \n", getCombat().getAmmo());
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"ammoInClip")==0)||(strcmp(command,"ammoC")==0))
	{
		sprintf(msgBuffer, "Ammo in clip: %d \n", getCombat().getAmmoInClip());
		getCommunication().sayText(msgBuffer);
	}
	else if(strcmp(command,"armour")==0)
	{
		sprintf(msgBuffer, "My armour is: %d \n", getCombat().armour());
		getCommunication().sayText(msgBuffer);
	}
	else if(strcmp(command,"inBuyZone")==0)
	{
		if(getFinances().inBuyZone())
			sprintf(msgBuffer, "I'm in the buy zone. \n");
		else
			sprintf(msgBuffer, "I'm not in the buy zone. \n");
		getCommunication().sayText(msgBuffer);
	}
	else if(strcmp(command,"withinBuyTime")==0)
	{
		if(getFinances().withinBuyTime())
			sprintf(msgBuffer, "I'm within buy time. \n");
		else
			sprintf(msgBuffer, "I'm not within buy time. \n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"aimAtMe")==0)||(strcmp(command,"a")==0))
	{
		_isAiming = true;
		Vector offset(0, 0, 15);
		Vector senderOrigin = getNavigation().getPosition() + record.sender.radarUnit.direction * record.sender.radarUnit.distance;
		_aimTarget = senderOrigin + offset; 
		sprintf(msgBuffer, "Aiming at you... \n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"aimL")==0) || (strcmp(command,"aL")==0))
	{
		records[Operations::aimLeft].enabled = true;
		if(util::isNullString(arg1))
			records[Operations::aimLeft].timeout = TIMEOUT_NOT_DEFINED;
		else
			records[Operations::aimLeft].timeout = getWorld().getTime() + atof(arg1);
		sprintf(msgBuffer, "Aiming left...\n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"aimR")==0) || (strcmp(command,"aR")==0))
	{
		records[Operations::aimRight].enabled = true;
		if(util::isNullString(arg1))
			records[Operations::aimRight].timeout = TIMEOUT_NOT_DEFINED;
		else
			records[Operations::aimRight].timeout = getWorld().getTime() + atof(arg1);
		sprintf(msgBuffer, "Aiming right...\n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"aimU")==0) || (strcmp(command,"aU")==0))
	{
		records[Operations::aimUp].enabled = true;
		if(util::isNullString(arg1))
			records[Operations::aimUp].timeout = TIMEOUT_NOT_DEFINED;
		else
			records[Operations::aimUp].timeout = getWorld().getTime() + atof(arg1);
		sprintf(msgBuffer, "Aiming up...\n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(command,"aimD")==0) || (strcmp(command,"aD")==0))
	{
		records[Operations::aimDown].enabled = true;
		if(util::isNullString(arg1))
			records[Operations::aimDown].timeout = TIMEOUT_NOT_DEFINED;
		else
			records[Operations::aimDown].timeout = getWorld().getTime() + atof(arg1);
		sprintf(msgBuffer, "Aiming down...\n");
		getCommunication().sayText(msgBuffer);
	}
	else if((strcmp(record.msg,"moveToHere")==0) || (strcmp(command,"mH")==0))
	{
		Vector senderOrigin = getNavigation().getPosition() + record.sender.radarUnit.direction * record.sender.radarUnit.distance;
		getFreeNavigation().moveToDestination(senderOrigin);
		sprintf(msgBuffer, "Moving towards your current position (%.2f %.2f %.2f)...\n", 
			senderOrigin.x, senderOrigin.y, senderOrigin.z);
		getCommunication().sayText(msgBuffer);
	}
	else if(strcmp(command, "stop")==0)
	{
		stop();
		sprintf(msgBuffer, "Stopped.\n");
		getCommunication().sayText(msgBuffer);
	}
}